#ifndef DATACENTER_H
#define DATACENTER_H

#include"data.h"
#include"../network/netclient.h"

#include <QWidget>

namespace model {
class DataCenter : public QObject
{
    Q_OBJECT
public:
    static DataCenter* getInstance();
    ~DataCenter();
private:
    DataCenter();
    static DataCenter* instance;

    //列出DataCenter 中要组织管理的所有数据

    //当前客户端登录到服务器对应的登录会话id
    QString loginSessionId = "";

    //当前的用户信息
    UserInfo* myself = nullptr;

    //好友列表
    QList<UserInfo>* friendList = nullptr;

    //会话列表
    QList<ChatSessionInfo>* chatSessionList = nullptr;

    //记录当前选中的会话是哪个
    QString currentChatSessionId = "";

    //记录每个对话中，都有哪些成员(主要针对群聊)
    QHash<QString,QList<UserInfo>>* memberList = nullptr;

    //待处理的好友申请列表
    QList<UserInfo>* applyList = nullptr;

    //每个会话的最近消息列表,key为chatSessionId,value 为消息列表
    QHash<QString,QList<Message>>* recentMessages = nullptr;

    //存储每个会话，未读消息的个数,key为chatSessionId,value为未读消息的个数
    QHash<QString,int>* unreadMessageCount = nullptr;

    //用户的好友搜索结果
    QList<UserInfo>* searchUserResult = nullptr;

    //历史消息搜索结果
    QList<Message>* searchMessageResult = nullptr;

    //短信验证码的验证id
    QString currentVerifyCodeId = "";

   //让DataCenter持有NetClient
    network::NetClient netClient;

public:
    //初始化数据文件
    void initDataFile();
    //存储数据到文件中
    void saveDataFile();
    //从数据文件中加载数据到内存
    void loadDataFile();
    //清空未读消息数目
    void clearUnread(const QString& chatSessionId);
    //增加未读消息数目
    void addUnread(const QString& chatSessionId);
    //获取未读消息数目
    int getUnread(const QString& chatSessionId);

    //获取到当前的登录会话id
    const QString& getLoginSessionId() const {
        return loginSessionId;
    }


    //验证网络联通性
    void ping(){netClient.ping();}

    //针对netClient中的websocket进行初始化
    void initWebsocket();

//////////////////////////////////////////////////
////// 核心函数
//////////////////////////////////////////////////

    //通过网络获取到用户的个人信息,该函数是一个"异步函数",只负责把HTTP请求发出去就不管了。
    void getMyselfAsync();
    UserInfo* getMyself();
    void resetMyself(std::shared_ptr<bite_im::GetUserInfoRsp> resp);

    //通过网络获取到用户的好友列表
    void getFriendListAsync();
    QList<UserInfo>* getFriendList();
    void resetFriendList(std::shared_ptr<bite_im::GetFriendListRsp> resp);

    //通过网络获取到用户的会话列表
    void getChatSessionListAsync();
    QList<ChatSessionInfo>* getChatSessionList();
    void resetChatSessionList(std::shared_ptr<bite_im::GetChatSessionListRsp> resp);

    //通过网络获取到用户的好友申请列表
    void getApplyListAsync();
    QList<UserInfo>* getApplyList();
    void resetApplyList(std::shared_ptr<bite_im::GetPendingFriendEventListRsp> resp);

    //获取最近消息列表
    void getRecentMessageListAsync(const QString& chatSessionId,bool updateUI);
    QList<Message>* getRecentMessageList(const QString& chatSessionId);
    void resetRecentMessageList(const QString& chatSessionId,std::shared_ptr<bite_im::GetRecentMsgRsp> resp);

    //发送消息给服务器
    void sendTextMessageAsync(const QString& chatSessionId,const QString& content);
    void sendImageMessageAsync(const QString& chatSessionId,const QByteArray& content);
    void sendFileMessageAsync(const QString& chatSessionId,const QString& fileName,const QByteArray& content);
    void sendSpeechMessageAsync(const QString& chatSessionId,const QByteArray& content);

    //修改用户昵称
    void changeNicknameAsync(const QString& nickname);
    void resetNickname(const QString& nickname);

    //修改用户签名
    void changeDescriptionAsync(const QString& desc);
    void resetDescription(const QString& desc);

    //获取短信验证码
    void getVerifyCodeAsync(const QString& phone);
    void resetVerifyCodeId(const QString& verifyCodeId);
    //获取verifyCodeId
    const QString& getVerifyCodeId();

    //修改手机号码
    void changePhoneAsync(const QString& phone,const QString& verifyCodeId,const QString& verifyCode);
    void resetPhone(const QString& phone);

    //修改头像
    void changeAvatarAsync(const QByteArray& imageBytes);
    void resetAvatar(const QByteArray& avatar);

    //删除好友
    void deleteFriendAsync(const QString& userId);
    void removeFriend(const QString& userId);

    //发送好友申请
    void addFriendApplyAsync(const QString& userId);

    //发送同意好友申请操作
    void acceptFriendApplyAsync(const QString& userId);
    model::UserInfo removeFromApplyList(const QString& userId);

    //拒绝好友申请操作
    void rejectFriendApplyAsync(const QString& userId);

    //修改群聊名称
    void changeGroupNameAsync(const QString& groupName);
    void resetGroupName(const QString& chatSessionId,const QString& groupName);

    //搜索用户
    void searchUserAsync(const QString& searchKey);
    QList<UserInfo>* getSearchUserResult();
    void resetSearchUserResult(const QList<bite_im::UserInfo>& userList);

    //搜索历史消息
    void searchMessageByKeyAsync(const QString& searchKey);
    void searchMessageByTimeAsync(const QDateTime& begTime,const QDateTime& endTime);
    QList<Message>* getSearchMessageResult();
    void resetSearchMessageResult(const QList<bite_im::MessageInfo>& msgList);

    //登录注册
    void userLoginAsync(const QString& username,const QString& password);
    void resetLoginSessionId(const QString& loginSessionId);
    void userRegisterAsync(const QString& username,const QString& password);
    void phoneLoginAsync(const QString& phone,const QString& verifyCode);
    void phoneRegisterAsync(const QString& phone,const QString& verifyCode);

    //获取单个文件
    void getSingleFileAsync(const QString& fileId);

    //语音转文字
    void speechConvertTextAsync(const QString& fileId,const QByteArray& content);

//////////////////////////////////////////////////
////// 辅助函数
//////////////////////////////////////////////////

    //根据会话id查询会话信息
    ChatSessionInfo* findChatSessionByChatSessionId(const QString& chatSessionid);
    //根据用户id查询会话信息
    ChatSessionInfo* findChatSessionByUserId(const QString& userId);
    //把指定的会话信息，放到列表头部
    void topChatSessionInfo(const ChatSessionInfo& chatSessionInfo);
    //根据用户id查询好友信息
    model::UserInfo* findFriendById(const QString& userId);

    //保存/设置当前讯中的会话
    void setCurrentChatSessionId(const QString& chatSessionId);
    const QString& getCurrentChatSessionId();

    //添加消息到DataCenter中
    void addMessage(const model::Message& message);

    //创建群聊
    void createGroupChatSessionAsync(const QList<QString>& userIdList);

    //获取会话的成员列表
    void getMemberListAsync(const QString& chatSessionId);
    QList<UserInfo>* getMemberList(const QString& chatSessionId);
    void resetMemberList(const QString& chatSessionId,const QList<bite_im::UserInfo>& memberList);


signals:
    //自定义信号
    void getMyselfDone();
    void getFriendListDone();
    void getChatSessionListDone();
    void getApplyListDone();
    void getRecentMessageListDone(const QString& chatSessionId);
    void getRecentMessageListDoneNoUI(const QString& chatSessionId);
    void sendMessageDone(MessageType messageType,const QByteArray& content,const QString& extraInfo);
    void updateLastMessage(const QString& chatSessionId);
    void receiveMessageDone(const Message& lastMessage);
    void changeNicknameDone();
    void changeDescriptionDone();
    void getVerifyCodeDone();
    void changePhoneDone();
    void changeAvatarDone();
    void deleteFriendDone();
    void clearCurrentSession();
    void addFriendApplyDone();
    void receiveFriendApplyDone();
    void acceptFriendApplyDone();
    void rejectFriendApplyDone();
    void receiveFriendProcessDone(const QString& nickname,bool agree);
    void createGroupChatSessionDone();
    void receiveSessionCreateDone();
    void getMemberListDone(const QString& chatSessionId);
    void changeGroupNameDone(const QString& chatSessionId);
    void searchUserDone();
    void searchMessageDone();
    void userLoginDone(bool ok,const QString& reason);
    void userRegisterDone(bool ok,const QString& reason);
    void phoneLoginDone(bool ok,const QString& reason);
    void phoneRegisterDone(bool ok,const QString& reason);
    void getSingleFileDone(const QString& fileId,const QByteArray& fileContent);
    void speechConvertTextDone(const QString& fileId,const QString& text);
};

}//end namespace

#endif // DATACENTER_H
